--[[
##############################################
##-
##-  WrackSpams (Based on coding from Cyrila's VisualRaid Addon :D)
##-  By Cyrila <Inner Sanctum> @ Silvermoon-EU & Mosphet <Vex> @ Bloodfeather-EU
##-
##-  Wracking Tracking for Sinestra
##-
##-
##-   * Copyright (C) 2011
##-   *
##-   * This program is free software: you can redistribute it and/or modify
##-   * it under the terms of the GNU General Public License as published by
##-   * the Free Software Foundation, either version 3 of the License, or
##-   * (at your option) any later version.
##-   *
##-   * This program is distributed in the hope that it will be useful,
##-   * but WITHOUT ANY WARRANTY; without even the implied warranty of
##-   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##-   * GNU General Public License for more details.
##-   *
##-   * You should have received a copy of the GNU General Public License
##-   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
##-
##############################################
]]

local addon = LibStub("AceAddon-3.0"):NewAddon("WrackSpams", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0", "AceComm-3.0")
_G.WrackSpams = addon
addon.callbacks = LibStub("CallbackHandler-1.0"):New(addon)
addon.media = LibStub("LibSharedMedia-3.0")

-- --------------------------
--	Globals
-- --------------------------
local fontlol = "Interface\\AddOns\\WrackSpams\\media\\font.ttf"
local fontsize = 9
local fontflags = "OUTLINE, MONOCHROME"
local texture = "Interface\\AddOns\\WrackSpams\\media\\statusbar.tga"


-- --------------------------
--	Cyrila bar stuff....FUCK
-- --------------------------
local CyBar = LibStub("LibCyrilaBars-1.0")
local CyBarHeaders = {}
local CyBarData = {}


-- --------------------------------
--  Database Default Shit
-- --------------------------------

local db
local defaults = {
	profile = {
		sound = true,
		showWrack = true,
		effects = true,
		barsettings = {
			["Global"] = {
				isglobal = true,
				x = 0,
				y = 0,
			},
			["WrackSpams_Timer"] = {
				name = "WrackSpams_Timer",
				x = 0,
				y = 50,
			},
		},
	},
}


local WrackID = {
	[92955] = {},
}

-- ------------------------
--	Wrappers for ease (Stealing from Cyrila? Never. Just a learning tool xD)
-- ------------------------

function addon:print(s)
	DEFAULT_CHAT_FRAME:AddMessage("|cFFFFCC00[addon]|r "..s)
end

function addon:debug(s)
	if(debug) then
		DEFAULT_CHAT_FRAME:AddMessage("|cFFFFCC00[addon Debug]|r "..s)
	end
end

function addon:error(s, l)
	error(s, l)
end


-- -------------------------
--	Waffles Stuff
-- -------------------------

function addon:OnInitialize()
	-- Init
	self.db = LibStub("AceDB-3.0"):New("WrackSpamsDB", defaults, "Default")
	db = self.db.profile
	
	--if not db.disabled then
	--	self:SetEnabledState(true)
	--else
	--	self:SetEnabledState(false)
	--end
	
	self.media:Register("statusbar", "WrackSpams", [[Interface\AddOns\WrackSpams\media\statusbar.tga]])
	
	self:RegisterChatCommand("wrs", "SlashHandler");
	self:RegisterChatCommand("wrack", "SlashHandler");
	self:RegisterChatCommand("wrackspams", "SlashHandler");
end

function addon:OnEnable()
	-- ENABLED
	self:SpawnHeaders()
	self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", "COMBAT_LOG_EVENT_UNFILTERED");
end

function addon:OnDisable()
	self:print("WrackSpams Disabled. /addon standby to turn back on");
end

function addon:SlashHandler(input)
	input = self:Explode(" ", string.lower(input))
	if(input[1] == "lock") then
		self:UnlockHeaders()
	elseif(input[1] == "test") then
		self:NewTimerBar("WrackSpams_Timer", "testbar", "Wrack #1", 10)
		self:ScheduleTimer("ClearBarCache", 10, "testbar")
		self:NewTimerBar("WrackSpams_Timer", "testbar2", "Wrack #2", 12)
		self:ScheduleTimer("ClearBarCache", 12, "testbar2")
		self:NewTimerBar("WrackSpams_Timer", "testbar3", "Wrack #3", 10)
		self:ScheduleTimer("ClearBarCache", 10, "testbar3")
		self:NewTimerBar("WrackSpams_Timer", "testbar4", "Wrack #4", 20)
		self:ScheduleTimer("ClearBarCache", 20, "testbar4")
		self:NewTimerBar("WrackSpams_Timer", "testbar5", "Wrack #5", 20)
		self:ScheduleTimer("ClearBarCache", 20, "testbar5")
	else
		DEFAULT_CHAT_FRAME:AddMessage("|cFFFFCC00WrackSpams help:")
		DEFAULT_CHAT_FRAME:AddMessage("|cFFCC9900   Lock|r - Toggles lock/unlock movable bars.")
		DEFAULT_CHAT_FRAME:AddMessage("|cFFCC9900   Test|r - Shows test Wrack bars.")
		DEFAULT_CHAT_FRAME:AddMessage("|cFFCC9900   Help|r - Shows help.")
		DEFAULT_CHAT_FRAME:AddMessage("|cFFCC1100   This addon has no config. Only moving bars xD")
	end
end


-- ---------------------------
--	Cumbat log (Very funny Cyrila. Here's one, what do you call a melee resto druid? A COMBAT LOG! yeeeee)
-- ---------------------------

function addon:COMBAT_LOG_EVENT_UNFILTERED(_, timestamp, event, _, sourceGUID, sourceName, _, destGUID, destName, _, spellid, spellname, _, arg1, arg2)
	-- Nil	
	if not spellid then return end	
	local spell = WrackID[spellid]
	if not spell then return end
	
	if not spell.event then
		if(event == "SPELL_AURA_APPLIED") then
			_, _, _, _, _, spell.dur, _, _, _, _, _ = UnitAura(destName, spellname)
		elseif(event == "SPELL_AURA_REMOVED") then
			self:RemoveBar("active"..destName..spellname)
			return
		else
			return
		end
	else
		if spell.event ~= event then return end
	end
	
	local _, _, icon, _, _, _, _, _, _ = GetSpellInfo(spellid)
	local classcolor = RAID_CLASS_COLORS[select(2,UnitClass(destName))]
	classcolor = {classcolor.r, classcolor.g, classcolor.b}
	if db.showWrack then
		local id = "active"..destName..spellname
		self:ScheduleTimer("ClearBarCache", spell.dur, id)
		self:NewTimerBar("WrackSpams_Timer", id, ("%s"):format(destName), spell.dur, icon, classcolor)
	end
end


-- ------------------------------
--	BAR stuff. (Uhm, yea awsum work confusing me here ._.)
-- ------------------------------

local locked
function addon:UnlockHeaders()
	for header in pairs(CyBarHeaders) do
		if not locked then
			header:Show()
		else
			db.barsettings[header.name].x = header.data.x
			db.barsettings[header.name].y = header.data.y
			db.barsettings[header.name].point = header.data.point
			db.barsettings[header.name].rpoint = header.data.rpoint
			header:Hide()
		end
	end
	locked = not locked
end

function addon:SpawnHeaders()
	local t = {}
	t.LabelFont = fontlol
	t.LabelFontSize = fontsize
	t.LabelFontFlags = fontflags
	
	t.TimerFont = fontlol
	t.TimerFontSize = fontsize
	t.TimerFontFlags = fontflags

	t.BarTexture = texture

	for k,v in pairs(db.barsettings) do
		if not v.isglobal then
			local header = CyBar:SpawnHeader(k, v.x, v.y, v.point, v.rpoint, t)
			CyBarHeaders[header] = true
		end
	end
end

function addon:NewTimerBar(header, id, label, timeleft, icon, colors)
	if CyBarData[id] then
		if CyBarData[id]:IsRunning() then return end
	end
	CyBarData[id] = CyBar:NewBar(header, id, label, timeleft, icon, colors)
end

function addon:RemoveBar(id)
	if not CyBarData[id] then return end
	if not CyBarData[id]:IsRunning() then return end
	CyBarData[id]:Release()
	--CyBarData[id] = nil <-- Lazy xD
end

function addon:ClearBarCache(id)
	CyBarData[id] = nil
end


-- ------------------------------
--	Misc Stuff.
-- ------------------------------

function addon:Explode(d, str)
	local t, ll
	t={}
	ll=0
	if(#str == 1) then return str end
		while true do
			l=strfind(str, d, ll+1, true)
			if l~=nil then
				tinsert(t, strsub(str, ll, l-1))
				ll=l+1
			else
				tinsert(t, strsub(str,ll))
				break
			end
		end
	return t
end